﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Threading;
using System.Diagnostics;

namespace BehaviorFramework
{
    public class BehaviorCommand : ICommand
    {
        private Dispatcher _uiDispatcher = Dispatcher.CurrentDispatcher;

        public BehaviorCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            ExecuteAction = execute;
            CanExecuteFunc = canExecute;
        }
        [NonObservable]
        protected internal string Name { get; set; }
        [NonObservable]
        protected internal Func<object, bool> CanExecuteFunc { get; set; }
        [NonObservable]
        protected internal Action<object> ExecuteAction { get; set; }

        public List<ObservableProperty> DependsUpon = new List<ObservableProperty>();

        public event EventHandler CanExecuteChanged;

        protected internal void OnCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                _uiDispatcher.InvokeIfRequired(() => handler(this, new EventArgs()));
            }
        }

        public bool CanExecute(object parameter)
        {
            if (CanExecuteFunc != null)
            {
                return CanExecuteFunc(parameter);
            }
            else
            {
                return true;
            }
        }

        public void Execute(object parameter)
        {
            if (CanExecute(parameter))
            {
                ExecuteAction.Invoke(parameter);
                Debug.WriteLine("Executed command {0}", Name);
            }
            else
            {
                Debug.WriteLine("Cannot Execute command {0} CanExecute() == false", Name);
            }
        }
    }

}
